import path               from 'path';
import dotenv             from 'dotenv';
import webpack            from 'webpack';
import HtmlPlugin         from 'html-webpack-plugin';
import ExtractTextPlugin  from 'extract-text-webpack-plugin';
import offlinePlugin      from 'offline-plugin';
import PWAManifest        from 'webpack-pwa-manifest';
import utils              from './bins/utils';

// load base config
dotenv.config();
const env               = process.env;

/****************************************************
 * config entry
 ***************************************************/
let entry               = {};

// ./src/App.ts
entry.app               = [`.${path.sep}${env.DIRECTORY_SOURCE}${path.sep}${env.FILE_SOURCE_MAIN}`];
// ./src/modules/index.ts
entry.common            = [`.${path.sep}${env.DIRECTORY_SOURCE}${path.sep}${env.DIRECTORY_SOURCE_MODULES}${path.sep}${env.FILE_SOURCE_COMMON}`];
// entry.common            = [`.${path.sep}${env.DIRECTORY_SOURCE}${path.sep}${env.FILE_SOURCE_MAIN}`];

if ( 'development' === env.NODE_ENV ) {
  entry.app             = ['webpack-hot-middleware/client?reload=true'].concat(entry.app);
}

if ( 'server' === env.BUILD_TYPE ) {
  entry                 = {};
  entry.generated       = [`.${path.sep}${env.DIRECTORY_SOURCE}${path.sep}${env.FILE_SOURCE_MAIN_RENDER}`];
}
/****************************************************
 * config output
 ***************************************************/
const output            = {};
output.publicPath       = '/';
output.path             = path.join(__dirname, env.DIRECTORY_OUTPUT);
output.filename         = `${env.DIRECTORY_OUTPUT_STATIC}/js/[name]-[hash:5].js`;

if ( 'development' === env.NODE_ENV ) {
  output.path           = path.join(__dirname, env.DIRECTORY_DEVELOP);
  output.publicPath     = '/';
}

if( 'server' === env.BUILD_TYPE ) {
  output.path           = path.join(__dirname, env.DIRECTORY_SERVICE);
  output.libraryTarget  = 'commonjs2';
  output.filename       = `[name].js`
}


/****************************************************
 * config resolve
 ***************************************************/
const resolve           = {
  extensions        : ['.ts', '.tsx', '.vue', '.js'],
  alias: {
    // 'other_modules'  : path.resolve('other_modules'),
    'src'           : path.resolve('src'),
    'assets'        : path.resolve('src/assets'),
    'styles'        : path.resolve('src/styles'),
    'services'        : path.resolve('src/services'),
    'config'        : path.resolve('src/config'),
    'components'    : path.resolve('src/components'),
    'containers'    : path.resolve('src/containers'),
    'view'          : path.resolve('src/view'),
    'modules'       : path.resolve('src/modules'),
    'router'        : path.resolve('src/router'),
    'store'         : path.resolve('src/store'),
    'interface'     : path.resolve('src/interface'),
  }
};

/****************************************************
 * config module
 ***************************************************/
const styleCommon         = new ExtractTextPlugin(`${env.DIRECTORY_OUTPUT_STATIC}/${env.DIRECTORY_OUTPUT_STYLES}/common-[hash:5].css`);
const stylePrivate        = new ExtractTextPlugin(`${env.DIRECTORY_OUTPUT_STATIC}/${env.DIRECTORY_OUTPUT_STYLES}/style-[hash:5].css`);
const module            = {
  rules: []
};

//typescript
//----------------
// hot
//if ( 'development' === env.NODE_ENV ) {
//  module.rules.push({
//    test: /\.(ts|tsx)$/,
//    exclude: /node_modules/,
//    loader: 'react-hot-loader'
//  });
//}
// ts
module.rules.push({
  test: /\.(ts|tsx)$/,
  exclude: /node_modules/,
  loader: 'ts-loader',
  options: {
    appendTsSuffixTo: [/\.vue$/],
  },
  include: [path.resolve('src')]
});

// tslint
module.rules.push({
 test: /\.(ts|tsx)$/,
 enforce: 'pre',
 exclude: /node_modules/,
 loader: 'tslint-loader',
 include: [path.resolve('src')]
});

// vue
module.rules.push({
  test: /\.(vue)$/,
  // exclude: /node_modules/,
  loader: 'vue-loader',
  // include: [path.resolve('src'), path.resolve('node_modules/vue-antd')],
  include: [path.resolve('node_modules/element-ui'),path.resolve('src'), path.resolve('node_modules/echarts')],
  options: {
    cssModules: {
      localIdentName: '[local]-[hash:base64:5]',
      camelCase: true
    },
    loaders: {
      less: stylePrivate.extract( {
        use: [{
          loader: 'css-loader',
          options: {
            minimize: 'production' === env.NODE_ENV
          }
        },
          'autoprefixer-loader',
          'less-loader'
        ],
        fallback: 'vue-style-loader',
        publicPath: '/'
      }),
      css: stylePrivate.extract( {
        use: [{
          loader: 'css-loader',
          options: {
            minimize: 'production' === env.NODE_ENV
          }
        },
          'autoprefixer-loader'
        ],
        fallback: 'vue-style-loader',
        publicPath: '/'
      })
    }
  }
});

// css
module.rules.push({
  test: /\.css/,
  loader: styleCommon.extract( {
    use: [{
        loader: 'css-loader',
        options: {
          minimize: 'production' === env.NODE_ENV
        }
      }],
    publicPath: '/'
  })
});

// less
module.rules.push({
  test: /\.less/,
  loader: stylePrivate.extract( {
    use: [{
      loader: 'css-loader',
      options: {
        minimize: 'production' === env.NODE_ENV
      }
    },
      'autoprefixer-loader',
      'less-loader'
    ],
    publicPath: '/'
  })
});

// less
module.rules.push({
  test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
  loader: 'url-loader',
  query: {
    limit: 1000,
    name: `${env.DIRECTORY_OUTPUT_STATIC}/${env.DIRECTORY_OUTPUT_RESOURCE}/[name]-[hash:5].[ext]`,
    publicPath: '/'
  }
});

// ttf
module.rules.push({
  test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
  loader: 'url-loader',
  query: {
    limit: 1000,
    name: `${env.DIRECTORY_OUTPUT_STATIC}/${env.DIRECTORY_OUTPUT_RESOURCE}/[name]-[hash:5].[ext]`,
    publicPath: '/'
  }
});

/****************************************************
 * config plugins
 ***************************************************/
const plugins           = [ stylePrivate, styleCommon ];

plugins.push( new webpack.DefinePlugin(utils.getConfigDefinePlugin()) );

if ( 'production' === env.NODE_ENV && 'server' !== env.BUILD_TYPE  ) {
  plugins.push( new offlinePlugin());
  plugins.push( new webpack.optimize.UglifyJsPlugin(utils.getConfigOptimize()));
}
plugins.push( new PWAManifest(utils.getConfigPWAManifest()));
if ( 'development' === env.NODE_ENV ) {
  plugins.push( new webpack.HotModuleReplacementPlugin() );
  plugins.push( new webpack.NoEmitOnErrorsPlugin() );
}

if( 'server' !== env.BUILD_TYPE ) {
  plugins.push( new HtmlPlugin(utils.getConfigHtmlTemplate()) );
  plugins.push( new webpack.optimize.CommonsChunkPlugin(utils.getConfigCommons()));
}

/****************************************************
 * config target
 ***************************************************/
let target              = 'web';

if( 'server' === env.BUILD_TYPE ) {
  target                = 'node';
}

export default { entry, output, module, resolve, plugins, target };
